# extract_table.py
# usage:
# python ./src/query/extract_tables.py --sql "WITH yearly_stats AS ( SELECT strftime('%Y', busi_time) AS year, CAST(SUM(satis_num) AS REAL) / CAST(SUM(item_num) AS REAL) AS satisfaction_rate FROM items_total_day WHERE strftime('%Y', busi_time) IN ('2024', '2025') AND item_num > 0  GROUP BY strftime('%Y', busi_time) ) SELECT ROUND( ( (SELECT satisfaction_rate FROM yearly_stats WHERE year = '2025') - (SELECT satisfaction_rate FROM yearly_stats WHERE year = '2024') ) / (SELECT satisfaction_rate FROM yearly_stats WHERE year = '2024') * 100, 2 ) AS yoy_growth_rate_percent;"
# python ./src/query/extract_tables.py --sql "SELECT AVG(complete_avg_time) AS 区县单位工单平均处理时长 FROM assess_items_total_day WHERE strftime('%Y-%m', busi_time)='2024-01' AND dept_type =2;"

"""
extract_tables.py
功能：从给定的SQL语句中提取出预定义的库表集合中的表名
"""

import os,sys
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.insert(0, project_root)
from config import project_config
import argparse


def extract_tables(sql):
    """
    使用字符串匹配方式，检查SQL中是否包含table_list中的表名。
    要求表名前面必须有空格、逗号、左括号等分隔符（即不能是标识符的一部分）。

    Args:
        sql (str): 输入的SQL语句

    Returns:
        list: 在SQL中出现的表名列表（去重，保持顺序）
    """
    table_list = project_config.tables_list
    matched_tables = []
    sql_lower = sql.lower()

    # 定义合法的前边界字符（即表名前面可以出现的字符）
    # 也可以是字符串起始位置
    valid_prefix_chars = ' (,;'  # 空格、左括号、逗号、分号等

    for table in table_list:
        table_lower = table.lower()
        start = 0
        found = False
        while True:
            # 查找表名的位置
            pos = sql_lower.find(table_lower, start)
            if pos == -1:
                break  # 没有找到更多匹配

            # 检查前面是否是合法边界
            if pos == 0:
                # 表名在字符串开头，也算合法
                pass
            elif sql_lower[pos - 1] not in valid_prefix_chars:
                start = pos + 1
                continue  # 前面不是合法分隔符，跳过

            # 可选：检查后面是否也是边界（防止匹配到子串），比如 user 匹配到 username
            # 这里也加上后边界判断更安全
            next_pos = pos + len(table_lower)
            if next_pos < len(sql_lower):
                next_char = sql_lower[next_pos]
                if next_char.isalnum() or next_char == '_':
                    start = pos + 1
                    continue  # 后面是字母数字或下划线，说明是标识符的一部分，跳过

            # 所有条件满足，视为匹配
            matched_tables.append(table)
            found = True
            break  # 找到一次即可加入（避免重复添加）

        # 如果你想允许一个表出现多次也多次记录，可以去掉 break 并一直找下去
        # 但通常我们只关心是否出现，所以找到一次就够了

    return list(dict.fromkeys(matched_tables))  # 去重，保持顺序

def main():

    # 命令行参数解析
    parser = argparse.ArgumentParser(description='从SQL中提取指定的表名')
    parser.add_argument('--sql', type=str, required=True, help='输入的SQL语句')

    args = parser.parse_args()

    # 调用函数提取表
    matched_tables = extract_tables(args.sql)

    # 屏幕显示匹配的库表集合
    if matched_tables:
        print("匹配到的库表：")
        for table in matched_tables:
            print(f"  - {table}")
    else:
        print("未匹配到任何指定的库表。")


if __name__ == '__main__':
    main()